//
// Created by Win on 2016/7/14.
//
#include <stdlib.h>
#include <stdio.h>

#include "frcomm.h"
#include "frmem.h"
#include "frreport_comm.h"
#include "frbyte_buffer.h"
#include "frrmi_basetype.h"
#include "frrmi.h"

union int64_double_bits {
    int64_t int_bits;
    double double_bits;
};

union int32_float_bits {
    int32_t int_bits;
    float float_bits;
};


/*!
 *\brief 解析object内的变量 跳过注释
 *
 *\arg p_st_data 输入的数据
 *     p_st_body_data 上报数据输出列表
 *     i_use_request  请求 或者 响应(FR_YES:FR_NO)
 *     p_i_deep       递增序列号
 *     pp_rmi_head    上报信息列表
 *     pp_rmi_root    申请的结构体列表 (管理内存用)
 *     p_u32_passHandle handle
 *     p_parent        上一层结构体名
 *     p_prefix         前缀名 (例如 http.rmi  或者 rmi)
 *
 * \return              FR_SUCC
 *                      FR_FAIL
 *
 */
int skipCustomData(Frbyte_Packet *p_st_data, Frreport_body_data *p_st_body_data, int i_use_request
                   , int *p_i_deep, rmiDataParent **pp_rmi_head, rmiDataParent **pp_rmi_root
                   , uint32_t *p_u32_passHandle, char *p_parent, char *p_prefix)
{
    uint8_t u8_tc = 0;
    int i_ret = 0;

    if(p_st_data == NULL || p_st_body_data == NULL || p_i_deep == NULL || pp_rmi_head == NULL)
        return FR_FAIL;

    while (1)
    {
        i_ret = bytebuff_peek_char(p_st_data, &u8_tc);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
    
        switch (u8_tc)
        {
            case TC_BLOCKDATA:
            case TC_BLOCKDATALONG:
                readBlockHeader(p_st_data, p_st_body_data, i_use_request, p_i_deep, pp_rmi_head, pp_rmi_root
                        , p_u32_passHandle, p_parent, p_prefix);
                break;
        
            case TC_ENDBLOCKDATA:
                i_ret = bytebuff_skip(p_st_data, 1);
                if(i_ret == FR_FAIL)
                    return FR_FAIL;

                return FR_SUCC;
        
            default:
                i_ret = readObject0(p_st_data, p_st_body_data, i_use_request, p_i_deep, pp_rmi_head, pp_rmi_root, p_u32_passHandle, p_parent, p_prefix);
                if(i_ret == FR_FAIL)
                    return FR_FAIL;

                break;
        }
    }
    
}

/*!
 *\brief 读取UTF数据
 *
 *\arg p_st_data 输入的数据
 *
 * \return              NULL
 *                      UTF数据块
 *
 */
char* readUTF(Frbyte_Packet *p_st_data)
{
    uint16_t u16_len = 0;
    int i_ret = 0;
    char *p_value;

    i_ret = bytebuff_get_short(p_st_data, 2, &u16_len, BYTE_BIG_ENDIAN);
    if(i_ret == FR_FAIL)
        return NULL;

    p_value = (char *)frmalloc(u16_len + 1);
    if(p_value == NULL)
        return NULL;

    i_ret = bytebuff_get_bytes(p_st_data, p_value, u16_len);
    if(i_ret == FR_FAIL)
    {
        frfree(p_value);
        return NULL;
    }
    p_value[u16_len] = '\0';

    return p_value;

}


/*!
 *\brief 头部信息解析 ac ed 00 05
 *
 *\arg p_st_data 输入的数据
 *
 * \return              FR_SUCC
 *                      FR_FAIL
 *
 */
int readStreamHeader(Frbyte_Packet *p_st_data)
{
    uint16_t u16_magic = 0, u16_version = 0;
    int i_ret = 0;

    i_ret = bytebuff_get_short(p_st_data, 2, &u16_magic, BYTE_BIG_ENDIAN);
    if(i_ret == FR_FAIL || u16_magic != 0xaced)
        return FR_FAIL;

    i_ret = bytebuff_get_short(p_st_data, 2, &u16_version, BYTE_BIG_ENDIAN);
    if(i_ret == FR_FAIL || u16_version != 5)
        return FR_FAIL;

    return FR_SUCC;
}

/*!
 *\brief 查找句柄代表的class
 *
 *\arg p_rmi_head     所有申请的head结构体链表
 *     passHandle     handle
 *
 * \return              NULL
 *                      p_rmi_head
 *
 */
rmiDataParent* rmiTypeFind(rmiDataParent *p_rmi_head, int passHandle)
{
    rmiDataParent *p_rmi_head_tmp = NULL;
    
    if(p_rmi_head == NULL || passHandle < 0x7e0000)
        return NULL;

    p_rmi_head_tmp = p_rmi_head;
    
    while (p_rmi_head_tmp)
    {
        if(p_rmi_head_tmp->passhandle == passHandle)
            return p_rmi_head_tmp;
        
        p_rmi_head_tmp = p_rmi_head_tmp->next;
    }
    

    return NULL;

}


/*!
 *\brief rmi信息上报
 *
 *\arg p_st_data 输入的数据
 *     p_st_body_data 上报数据输出列表
 *     i_use_request  请求 或者 响应(FR_YES:FR_NO)
 *     p_i_deep       递增序列号
 *     pp_rmi_head    上报信息列表
 *     pp_rmi_root    申请的结构体列表 (管理内存用)
 *     p_u32_passHandle handle
 *     p_parent        上一层结构体名
 *     p_prefix         前缀名 (例如 http.rmi  或者 rmi)
 *
 * \return              FR_SUCC
 *                      FR_FAIL
 *
 */
int rmi_report(Frbyte_Packet *p_st_data, Frreport_body_data *p_st_body_data, int i_use_request
               , int *p_i_deep, rmiDataParent *p_rmi_head, rmiDataParent **pp_rmi_root
               , uint32_t *p_u32_passHandle, char *p_parent, char *p_prefix)
{
    char arr_key[256];
    int i_ret = 0;
    rmiDataParent *p_rmi_head_report = NULL;
    rmiDataParent *p_rmi_head_report_tmp = NULL;
    rmiDataParent *p_rmi_head_report_super = NULL;
    rmiDataParent *p_rmi_head_report_super_tmp = NULL;
    rmiDataChild *p_rmi_node = NULL;
    char *p_parent_tmp = NULL;
    
    union int64_double_bits u_64bits;
    uint64_t u64_tmp;
    double db_value = 0.0;
    
    union int32_float_bits u_32bits;
    uint32_t u32_tmp = 0;
    float fl_value = 0.0;
    
    if(p_st_data == NULL || p_st_body_data == NULL || p_i_deep == NULL || p_u32_passHandle == NULL)
        return FR_FAIL;

    //空的object
    if(p_rmi_head == NULL)
    {
        if(p_parent)
        {
            if(i_use_request)
                snprintf(arr_key, sizeof(arr_key), "request.%s.%d.%s.object", p_prefix, *p_i_deep, p_parent);
            else
                snprintf(arr_key, sizeof(arr_key), "response.%s.%d.%s.object", p_prefix, *p_i_deep, p_parent);
    
            (*p_i_deep)++;
            
            i_ret = frreport_body_l7_add_str(p_st_body_data, arr_key, "NULL");
            if(i_ret == FR_FAIL)
                return FR_FAIL;
    
            return FR_SUCC;
        }

        return FR_FAIL;
    }
    
    // 73  71  newhandle
    if(p_rmi_head->p_name == NULL)
    {
        p_rmi_head_report = rmiTypeFind(*pp_rmi_root, p_rmi_head->i_type_handle);
        if(p_rmi_head_report == NULL)
            return FR_FAIL;
    }
    else
    {
        p_rmi_head_report = p_rmi_head;
    }
    
    //object上报
    if(p_rmi_head_report->u8_tcode == 0)
    {
        if(p_rmi_head_report->p_name)
        {
            if(p_parent)
            {
                if(i_use_request)
                    snprintf(arr_key, sizeof(arr_key), "request.%s.%d.%s.object", p_prefix, *p_i_deep, p_parent);
                else
                    snprintf(arr_key, sizeof(arr_key), "response.%s.%d.%s.object", p_prefix, *p_i_deep, p_parent);
    
            }
            else
            {
                if(i_use_request)
                    snprintf(arr_key, sizeof(arr_key), "request.%s.%d.object", p_prefix, *p_i_deep);
                else
                    snprintf(arr_key, sizeof(arr_key), "response.%s.%d.object", p_prefix, *p_i_deep);
            }

            (*p_i_deep)++;
            i_ret = frreport_body_l7_add_str(p_st_body_data, arr_key, p_rmi_head_report->p_name);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
        }
        else
        {
            return FR_FAIL;
        }


        //超类
        if(p_rmi_head_report->super)
        {
            p_rmi_head_report_super = p_rmi_head_report->super;
            if(p_rmi_head_report_super->p_name == NULL)
            {
                p_rmi_head_report_super_tmp = rmiTypeFind(*pp_rmi_root, p_rmi_head_report_super->i_type_handle);
                if(p_rmi_head_report_super_tmp == NULL)
                    return FR_FAIL;
                
                if(p_parent)
                {
                    if(i_use_request)
                        snprintf(arr_key, sizeof(arr_key), "request.%s.%d.%s.%s.super", p_prefix, *p_i_deep, p_parent, p_rmi_head_report->p_name);
                    else
                        snprintf(arr_key, sizeof(arr_key), "response.%s.%d.%s.%s.super", p_prefix, *p_i_deep, p_parent, p_rmi_head_report->p_name);
                    
                }
                else
                {
                    if(i_use_request)
                        snprintf(arr_key, sizeof(arr_key), "request.%s.%d.%s.super", p_prefix, *p_i_deep, p_rmi_head_report->p_name);
                    else
                        snprintf(arr_key, sizeof(arr_key), "response.%s.%d.%s.super", p_prefix, *p_i_deep, p_rmi_head_report->p_name);
                }
    
                (*p_i_deep)++;
                i_ret = frreport_body_l7_add_str(p_st_body_data, arr_key, p_rmi_head_report_super_tmp->p_name);
                if(i_ret == FR_FAIL)
                    return FR_FAIL;
    
//                i_ret = rmi_report(p_st_data, p_st_body_data, i_use_request, p_i_deep, p_rmi_head_report_super_tmp
//                                   , pp_rmi_root, p_u32_passHandle, p_rmi_head_report_super_tmp->p_name, p_prefix);
//                if(i_ret == FR_FAIL)
//                    return FR_FAIL;
            }
            else
            {
                
                if(i_use_request)
                    snprintf(arr_key, sizeof(arr_key), "request.%s.%d.%s.super", p_prefix, *p_i_deep, p_rmi_head_report->p_name);
                else
                    snprintf(arr_key, sizeof(arr_key), "response.%s.%d.%s.super", p_prefix, *p_i_deep, p_rmi_head_report->p_name);
    
                (*p_i_deep)++;
                i_ret = frreport_body_l7_add_str(p_st_body_data, arr_key, p_rmi_head_report_super->p_name);
                if(i_ret == FR_FAIL)
                    return FR_FAIL;
    
//                i_ret = rmi_report(p_st_data, p_st_body_data, i_use_request, p_i_deep, p_rmi_head_report_super
//                                   , pp_rmi_root, p_u32_passHandle, p_rmi_head_report_super->p_name, p_prefix);
//                if(i_ret == FR_FAIL)
//                    return FR_FAIL;
            }

        }
        
        //内部参数上报
        p_parent_tmp = p_rmi_head_report->p_name;
        if(p_rmi_head_report->child)
        {
            p_rmi_node = p_rmi_head_report->child->head_node;
            p_parent_tmp = p_rmi_head_report->p_name;
        }

        while (p_rmi_node)
        {
            i_ret = rmi_report(p_st_data, p_st_body_data, i_use_request, p_i_deep
                               , p_rmi_node->child, pp_rmi_root, p_u32_passHandle, p_parent_tmp, p_prefix);
            if(i_ret == FR_FAIL)
                return FR_FAIL;

            p_rmi_node = p_rmi_node->next_node;
        }

        return FR_SUCC;

    }
    
    //基本变量上报
    switch (p_rmi_head_report->u8_tcode)
    {
        case 'Z':
        case 'B':
            if(p_parent)
            {
                if(i_use_request)
                    snprintf(arr_key, sizeof(arr_key), "request.%s.%d.%s.%s", p_prefix, *p_i_deep, p_parent, p_rmi_head_report->p_name);
                else
                    snprintf(arr_key, sizeof(arr_key), "response.%s.%d.%s.%s", p_prefix, *p_i_deep, p_parent, p_rmi_head_report->p_name);
            }
            else
            {
                if(i_use_request)
                    snprintf(arr_key, sizeof(arr_key), "request.%s.%d.%s", p_prefix, *p_i_deep, p_rmi_head_report->p_name);
                else
                    snprintf(arr_key, sizeof(arr_key), "response.%s.%d.%s", p_prefix, *p_i_deep, p_rmi_head_report->p_name);
            }
        
            (*p_i_deep)++;
            
            i_ret = bytebuff_get_long(p_st_data, 1, &u64_tmp, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;

            i_ret = frreport_body_l7_add_long(p_st_body_data, arr_key, (long)u64_tmp);
            if(i_ret == FR_FAIL)
                return FR_FAIL;


            break;

            //Short
        case 'C':
        case 'S':
            if(p_parent)
            {
                if(i_use_request)
                    snprintf(arr_key, sizeof(arr_key), "request.%s.%d.%s.%s", p_prefix, *p_i_deep, p_parent, p_rmi_head_report->p_name);
                else
                    snprintf(arr_key, sizeof(arr_key), "response.%s.%d.%s.%s", p_prefix, *p_i_deep, p_parent, p_rmi_head_report->p_name);
            }
            else
            {
                if(i_use_request)
                    snprintf(arr_key, sizeof(arr_key), "request.%s.%d.%s", p_prefix, *p_i_deep, p_rmi_head_report->p_name);
                else
                    snprintf(arr_key, sizeof(arr_key), "response.%s.%d.%s", p_prefix, *p_i_deep, p_rmi_head_report->p_name);
            }
        
            (*p_i_deep)++;
            i_ret = bytebuff_get_long(p_st_data, 2, &u64_tmp, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;

            i_ret = frreport_body_l7_add_long(p_st_body_data, arr_key, (long)u64_tmp);
            if(i_ret == FR_FAIL)
                return FR_FAIL;


            break;

            //Int
        case 'I':
            if(p_parent)
            {
                if(i_use_request)
                    snprintf(arr_key, sizeof(arr_key), "request.%s.%d.%s.%s", p_prefix, *p_i_deep, p_parent, p_rmi_head_report->p_name);
                else
                    snprintf(arr_key, sizeof(arr_key), "response.%s.%d.%s.%s", p_prefix, *p_i_deep, p_parent, p_rmi_head_report->p_name);
            }
            else
            {
                if(i_use_request)
                    snprintf(arr_key, sizeof(arr_key), "request.%s.%d.%s", p_prefix, *p_i_deep, p_rmi_head_report->p_name);
                else
                    snprintf(arr_key, sizeof(arr_key), "response.%s.%d.%s", p_prefix, *p_i_deep, p_rmi_head_report->p_name);
            }
            
            (*p_i_deep)++;
            
            i_ret = bytebuff_get_long(p_st_data, 4, &u64_tmp, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;

            i_ret = frreport_body_l7_add_long(p_st_body_data, arr_key, (long)u64_tmp);
            if(i_ret == FR_FAIL)
                return FR_FAIL;

            break;

            //Long
        case 'J':
            if(p_parent)
            {
                if(i_use_request)
                    snprintf(arr_key, sizeof(arr_key), "request.%s.%d.%s.%s", p_prefix, *p_i_deep, p_parent, p_rmi_head_report->p_name);
                else
                    snprintf(arr_key, sizeof(arr_key), "response.%s.%d.%s.%s", p_prefix, *p_i_deep, p_parent, p_rmi_head_report->p_name);
            }
            else
            {
                if(i_use_request)
                    snprintf(arr_key, sizeof(arr_key), "request.%s.%d.%s", p_prefix, *p_i_deep, p_rmi_head_report->p_name);
                else
                    snprintf(arr_key, sizeof(arr_key), "response.%s.%d.%s", p_prefix, *p_i_deep, p_rmi_head_report->p_name);
            }
        
            (*p_i_deep)++;
            
            i_ret = bytebuff_get_long(p_st_data, 8, &u64_tmp, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;

            i_ret = frreport_body_l7_add_long(p_st_body_data, arr_key, (long)u64_tmp);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
            
            break;
    
        case 'F':
            i_ret = bytebuff_get_int(p_st_data, 4, &u32_tmp, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
        
            u_32bits.int_bits = u32_tmp;
            fl_value = u_32bits.float_bits;
        
            i_ret = frreport_body_l7_add_float(p_st_body_data, arr_key, fl_value);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
        
            break;
            
        case 'D':
            i_ret = bytebuff_get_long(p_st_data, 8, &u64_tmp, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
        
            u_64bits.int_bits = u64_tmp;
            db_value = u_64bits.double_bits;
        
            i_ret = frreport_body_l7_add_double(p_st_body_data, arr_key, db_value);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
            
            break;

        case '[':
        case 'L':

            //name
            if(p_parent)
            {
                if(i_use_request)
                    snprintf(arr_key, sizeof(arr_key), "request.%s.%d.%s.object", p_prefix, *p_i_deep, p_parent);
                else
                    snprintf(arr_key, sizeof(arr_key), "response.%s.%d.%s.object", p_prefix, *p_i_deep, p_parent);
            }
            else
            {
                if(i_use_request)
                    snprintf(arr_key, sizeof(arr_key), "request.%s.%d.object", p_prefix, *p_i_deep);
                else
                    snprintf(arr_key, sizeof(arr_key), "response.%s.%d.object", p_prefix, *p_i_deep);
            }
            
//            (*p_i_deep)++;
            
//            i_ret = frreport_body_l7_add_str(p_st_body_data, arr_key, p_rmi_head_report->p_name);
//            if(i_ret == FR_FAIL)
//                return FR_FAIL;
            
            //type
            if(i_use_request)
                snprintf(arr_key, sizeof(arr_key), "request.%s.%d.%s.type", p_prefix, *p_i_deep, p_rmi_head->p_name);
            else
                snprintf(arr_key, sizeof(arr_key), "response.%s.%d.%s.type", p_prefix, *p_i_deep, p_rmi_head->p_name);
//            (*p_i_deep)++;
            
            if(p_rmi_head_report->p_object_type)
            {
//                i_ret = frreport_body_l7_add_str(p_st_body_data, arr_key, p_rmi_head_report->p_object_type);
//                if(i_ret == FR_FAIL)
//                    return FR_FAIL;
            }
            else
            {
                p_rmi_head_report_tmp = rmiTypeFind(*pp_rmi_root, p_rmi_head_report->i_type_handle);
                if(p_rmi_head_report_tmp == NULL)
                    return FR_FAIL;
    
//                i_ret = frreport_body_l7_add_str(p_st_body_data, arr_key, p_rmi_head_report_tmp->p_object_type);
//                if(i_ret == FR_FAIL)
//                    return FR_FAIL;
            }
        
            i_ret = readObject0(p_st_data, p_st_body_data, i_use_request, p_i_deep, &p_rmi_head_report, pp_rmi_root, p_u32_passHandle, p_parent, p_prefix);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
            
            break;

            //不是private
        default:
            return FR_FAIL;
    }


    return FR_SUCC;
}


/*!
 *\brief rmi 解析
 *
 *\arg p_st_data 输入的数据
 *     p_st_body_data 上报数据输出列表
 *     i_use_request  请求 或者 响应(FR_YES:FR_NO)
 *     p_i_deep       递增序列号
 *     pp_rmi_head    上报信息列表
 *     pp_rmi_root    申请的结构体列表 (管理内存用)
 *     p_u32_passHandle handle
 *     p_parent        上一层结构体名
 *     p_prefix         前缀名 (例如 http.rmi  或者 rmi)
 *
 * \return              FR_SUCC
 *                      FR_FAIL
 *
 */
int readObject(Frbyte_Packet *p_st_data, Frreport_body_data *p_st_body_data, int i_use_request, int *p_i_deep, char *p_prefix)
{
    int i_ret = 0;
    rmiDataParent *p_rmi_head = NULL;
    rmiDataParent *p_rmi_root = NULL;
    uint32_t u32_passHandle = 0x007e0000;

    if(p_st_data == NULL || p_st_body_data == NULL || p_i_deep == NULL)
        return FR_FAIL;


    //Object obj = readObject0(false);
    // if nested read, passHandle contains handle of enclosing object
    //class decs
    i_ret = readObject0(p_st_data, p_st_body_data, i_use_request, p_i_deep, &p_rmi_head, &p_rmi_root, &u32_passHandle, NULL, p_prefix);
    if(i_ret == FR_FAIL)
    {
        rmiHeadFree(p_rmi_root);
        return FR_FAIL;
    }

    rmiHeadFree(p_rmi_root);

    return i_ret;

}

/*!
 *\brief rmi 解析
 *
 *\arg p_st_data 输入的数据
 *     p_st_body_data 上报数据输出列表
 *     i_use_request  请求 或者 响应(FR_YES:FR_NO)
 *     p_i_deep       递增序列号
 *     pp_rmi_head    上报信息列表
 *     pp_rmi_root    申请的结构体列表 (管理内存用)
 *     p_u32_passHandle handle
 *     p_parent        上一层结构体名
 *     p_prefix         前缀名 (例如 http.rmi  或者 rmi)
 *
 * \return              FR_SUCC
 *                      FR_FAIL
 *
 */
int yongyou_readObject(Frbyte_Packet *p_st_data, Frreport_body_data *p_st_body_data, int i_use_request, int *p_i_deep, char *p_prefix)
{
    int i_ret = 0;
    rmiDataParent *p_rmi_head = NULL;
    rmiDataParent *p_rmi_root = NULL;
    uint32_t u32_passHandle = 0x007e0000;

    if(p_st_data == NULL || p_st_body_data == NULL || p_i_deep == NULL)
        return FR_FAIL;


    //Object obj = readObject0(false);
    // if nested read, passHandle contains handle of enclosing object
    //class decs
    i_ret = yongyou_readObject0(p_st_data, p_st_body_data, i_use_request, p_i_deep, &p_rmi_head, &p_rmi_root, &u32_passHandle, NULL, p_prefix);
    if(i_ret == FR_FAIL)
    {
        rmiHeadFree(p_rmi_root);
        return FR_FAIL;
    }

    rmiHeadFree(p_rmi_root);

    return i_ret;

}

/*!
 *\brief rmi各个类型 解析
 *
 *\arg p_st_data 输入的数据
 *     p_st_body_data 上报数据输出列表
 *     i_use_request  请求 或者 响应(FR_YES:FR_NO)
 *     p_i_deep       递增序列号
 *     pp_rmi_head    上报信息列表
 *     pp_rmi_root    申请的结构体列表 (管理内存用)
 *     p_u32_passHandle handle
 *     p_parent        上一层结构体名
 *     p_prefix         前缀名 (例如 http.rmi  或者 rmi)
 *
 * \return              FR_SUCC
 *                      FR_FAIL
 *
 */
int readObject0(Frbyte_Packet *p_st_data, Frreport_body_data *p_st_body_data, int i_use_request
                , int *p_i_deep, rmiDataParent **pp_rmi_head, rmiDataParent **pp_rmi_root
                , uint32_t *p_u32_passHandle, char *p_parent, char *p_prefix)
{
    uint8_t u8_tc = 0;
    int i_ret = 0;

    if(p_st_data == NULL || p_st_body_data == NULL || p_i_deep == NULL)
        return FR_FAIL;

    // handle previously written and non-replaceable objects
    i_ret = bytebuff_peek_char(p_st_data, &u8_tc);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    while (u8_tc == TC_RESET)
    {
        bytebuff_skip(p_st_data, 1);

        i_ret = bytebuff_peek_char(p_st_data, &u8_tc);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
    }

    switch (u8_tc)
    {
        case TC_NULL:
            i_ret = readNull(p_st_data, p_st_body_data, i_use_request, p_i_deep, pp_rmi_head, pp_rmi_root
                             , p_u32_passHandle, p_parent, p_prefix);
            break;

        case TC_REFERENCE:
            i_ret = readHandle(p_st_data, p_st_body_data, i_use_request, p_i_deep, pp_rmi_head, pp_rmi_root
                               , p_u32_passHandle, p_parent, p_prefix);
            break;

        case TC_CLASS:
            i_ret = readClass(p_st_data, p_st_body_data, i_use_request, p_i_deep, pp_rmi_head, pp_rmi_root
                              , p_u32_passHandle, p_parent, p_prefix);
            break;

        case TC_CLASSDESC:
        case TC_PROXYCLASSDESC:
            i_ret = readClassDesc(p_st_data, p_st_body_data, i_use_request, p_i_deep, pp_rmi_head, pp_rmi_root
                                  , p_u32_passHandle, p_parent, p_prefix);
            break;

        case TC_STRING:
        case TC_LONGSTRING:
            i_ret = readString(p_st_data, p_st_body_data, i_use_request, p_i_deep, pp_rmi_head, pp_rmi_root
                               , p_u32_passHandle, p_parent, p_prefix);
            break;

        case TC_ARRAY:
            i_ret = readArray(p_st_data, p_st_body_data, i_use_request, p_i_deep, pp_rmi_head, pp_rmi_root
                              , p_u32_passHandle, p_parent, p_prefix);
            break;

        case TC_ENUM:
            i_ret = readEnum(p_st_data, p_st_body_data, i_use_request, p_i_deep, pp_rmi_head, pp_rmi_root
                             , p_u32_passHandle, p_parent, p_prefix);
            break;

        case TC_OBJECT:
            i_ret = readOrdinaryObject(p_st_data, p_st_body_data, i_use_request, p_i_deep, pp_rmi_head
                                       , pp_rmi_root, p_u32_passHandle, p_parent, p_prefix);
            break;

        case TC_BLOCKDATA:
        case TC_BLOCKDATALONG:
            i_ret = readBlockHeader(p_st_data, p_st_body_data, i_use_request, p_i_deep, pp_rmi_head, pp_rmi_root
                    , p_u32_passHandle, p_parent, p_prefix);
            break;

        case TC_ENDBLOCKDATA:
            i_ret = bytebuff_skip(p_st_data, 1);
            break;

        default:
//            frwarn("invalid type code: %02X", u8_tc);
            return FR_FAIL;

    }

    return i_ret;

}

/*!
 *\brief rmi各个类型 解析
 *
 *\arg p_st_data 输入的数据
 *     p_st_body_data 上报数据输出列表
 *     i_use_request  请求 或者 响应(FR_YES:FR_NO)
 *     p_i_deep       递增序列号
 *     pp_rmi_head    上报信息列表
 *     pp_rmi_root    申请的结构体列表 (管理内存用)
 *     p_u32_passHandle handle
 *     p_parent        上一层结构体名
 *     p_prefix         前缀名 (例如 http.rmi  或者 rmi)
 *
 * \return              FR_SUCC
 *                      FR_FAIL
 *
 */
int yongyou_readObject0(Frbyte_Packet *p_st_data, Frreport_body_data *p_st_body_data, int i_use_request
        , int *p_i_deep, rmiDataParent **pp_rmi_head, rmiDataParent **pp_rmi_root
        , uint32_t *p_u32_passHandle, char *p_parent, char *p_prefix)
{
    uint8_t u8_tc = 0;
    int i_ret = 0;

    if(p_st_data == NULL || p_st_body_data == NULL || p_i_deep == NULL)
        return FR_FAIL;

    // handle previously written and non-replaceable objects
    i_ret = bytebuff_peek_char(p_st_data, &u8_tc);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    while (u8_tc == TC_RESET)
    {
        bytebuff_skip(p_st_data, 1);

        i_ret = bytebuff_peek_char(p_st_data, &u8_tc);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
    }

    switch (u8_tc)
    {
        case TC_NULL:
            i_ret = readNull(p_st_data, p_st_body_data, i_use_request, p_i_deep, pp_rmi_head, pp_rmi_root
                    , p_u32_passHandle, p_parent, p_prefix);
            break;

        case TC_REFERENCE:
            i_ret = readHandle(p_st_data, p_st_body_data, i_use_request, p_i_deep, pp_rmi_head, pp_rmi_root
                    , p_u32_passHandle, p_parent, p_prefix);
            break;

        case TC_CLASS:
            i_ret = readClass(p_st_data, p_st_body_data, i_use_request, p_i_deep, pp_rmi_head, pp_rmi_root
                    , p_u32_passHandle, p_parent, p_prefix);
            break;

        case TC_CLASSDESC:
        case TC_PROXYCLASSDESC:
            i_ret = readClassDesc(p_st_data, p_st_body_data, i_use_request, p_i_deep, pp_rmi_head, pp_rmi_root
                    , p_u32_passHandle, p_parent, p_prefix);
            break;

        case TC_STRING:
        case TC_LONGSTRING:
            i_ret = readString(p_st_data, p_st_body_data, i_use_request, p_i_deep, pp_rmi_head, pp_rmi_root
                    , p_u32_passHandle, p_parent, p_prefix);
            break;

        case TC_ARRAY:
            i_ret = readArray(p_st_data, p_st_body_data, i_use_request, p_i_deep, pp_rmi_head, pp_rmi_root
                    , p_u32_passHandle, p_parent, p_prefix);
            break;

        case TC_ENUM:
            i_ret = readEnum(p_st_data, p_st_body_data, i_use_request, p_i_deep, pp_rmi_head, pp_rmi_root
                    , p_u32_passHandle, p_parent, p_prefix);
            break;

        case TC_OBJECT:
            i_ret = readOrdinaryObject(p_st_data, p_st_body_data, i_use_request, p_i_deep, pp_rmi_head
                    , pp_rmi_root, p_u32_passHandle, p_parent, p_prefix);
            break;

        case TC_BLOCKDATA:
        case TC_BLOCKDATALONG:
            i_ret = readBlockHeader(p_st_data, p_st_body_data, i_use_request, p_i_deep, pp_rmi_head, pp_rmi_root
                    , p_u32_passHandle, p_parent, p_prefix);
            i_ret = readObject0(p_st_data, p_st_body_data, i_use_request, p_i_deep, pp_rmi_head
                    , pp_rmi_root, p_u32_passHandle, p_parent, p_prefix);
            break;

        case TC_ENDBLOCKDATA:
            i_ret = bytebuff_skip(p_st_data, 1);
            break;

        default:
//            frwarn("invalid type code: %02X", u8_tc);
            return FR_FAIL;

    }

    return i_ret;

}


/*!
 *\brief 参数类型解析
 *
 *\arg p_st_data 输入的数据
 *     p_st_body_data 上报数据输出列表
 *     i_use_request  请求 或者 响应(FR_YES:FR_NO)
 *     p_i_deep       递增序列号
 *     pp_rmi_head    上报信息列表
 *     pp_rmi_root    申请的结构体列表 (管理内存用)
 *     p_u32_passHandle handle
 *     p_parent        上一层结构体名
 *     p_prefix         前缀名 (例如 http.rmi  或者 rmi)
 *
 * \return              FR_SUCC
 *                      FR_FAIL
 *
 */
int readTypeString(Frbyte_Packet *p_st_data, Frreport_body_data *p_st_body_data, int i_use_request
                   , int *p_i_deep, rmiDataParent **pp_rmi_head, rmiDataParent **pp_rmi_root
                   , uint32_t *p_u32_passHandle, char *p_parent, char *p_prefix)
{
    int i_ret = 0;
    uint8_t u8_tc;
    
    if(p_st_data == NULL)
        return FR_FAIL;
    
    i_ret = bytebuff_peek_char(p_st_data, &u8_tc);
    if(i_ret == FR_FAIL)
        return FR_FAIL;
    
    switch (u8_tc)
    {
        case TC_NULL:
            i_ret = readNull(p_st_data, p_st_body_data, i_use_request, p_i_deep, pp_rmi_head, pp_rmi_root
                             , p_u32_passHandle, p_parent, p_prefix);
            break;
        
        case TC_REFERENCE:
            i_ret = readHandle(p_st_data, p_st_body_data, i_use_request, p_i_deep, pp_rmi_head, pp_rmi_root
                               , p_u32_passHandle, p_parent, p_prefix);
            break;
        
        case TC_STRING:
        case TC_LONGSTRING:
            i_ret = readString(p_st_data, p_st_body_data, i_use_request, p_i_deep, pp_rmi_head, pp_rmi_root
                               , p_u32_passHandle, p_parent, p_prefix);
            break;
        
        default:
//            frwarn("invalid type code: %02X", u8_tc);
            return FR_FAIL;
    }
    
    return i_ret;
    
}

/*!
 *\brief TC_NULL 解析
 *
 *\arg p_st_data 输入的数据
 *     p_st_body_data 上报数据输出列表
 *     i_use_request  请求 或者 响应(FR_YES:FR_NO)
 *     p_i_deep       递增序列号
 *     pp_rmi_head    上报信息列表
 *     pp_rmi_root    申请的结构体列表 (管理内存用)
 *     p_u32_passHandle handle
 *     p_parent        上一层结构体名
 *     p_prefix         前缀名 (例如 http.rmi  或者 rmi)
 *
 * \return              FR_SUCC
 *                      FR_FAIL
 *
 */
int readNull(Frbyte_Packet *p_st_data, Frreport_body_data *p_st_body_data, int i_use_request
             , int *p_i_deep, rmiDataParent **pp_rmi_head, rmiDataParent **pp_rmi_root
             , uint32_t *p_u32_passHandle, char *p_parent, char *p_prefix)
{
    uint8_t u8_tc = 0;
    int i_ret = 0;
    rmiDataParent *p_rmi_head = NULL;
    char arr_key[256];

    if(p_st_data == NULL || p_st_body_data == NULL || p_i_deep == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_st_data, &u8_tc);
    if(i_ret == FR_FAIL || u8_tc != TC_NULL)
        return FR_FAIL;

//    passHandle = NULL_HANDLE;
    if(pp_rmi_head && *pp_rmi_head)
    {
        p_rmi_head = *pp_rmi_head;
        p_rmi_head->i_type_handle = 0;

        if(p_rmi_head->p_name)
        {
            if(p_parent)
            {
                if(i_use_request)
                    snprintf(arr_key, sizeof(arr_key), "request.%s.%d.%s.%s", p_prefix, *p_i_deep, p_parent, p_rmi_head->p_name);
                else
                    snprintf(arr_key, sizeof(arr_key), "response.%s.%d.%s.%s", p_prefix, *p_i_deep, p_parent, p_rmi_head->p_name);
            }
            else
            {
                if(i_use_request)
                    snprintf(arr_key, sizeof(arr_key), "request.%s.%d.%s", p_prefix, *p_i_deep, p_rmi_head->p_name);
                else
                    snprintf(arr_key, sizeof(arr_key), "response.%s.%d.%s", p_prefix, *p_i_deep, p_rmi_head->p_name);
            }
            
            (*p_i_deep)++;
            i_ret = frreport_body_l7_add_str(p_st_body_data, arr_key, "NULL");
            if(i_ret == FR_FAIL)
                return FR_FAIL;
        }
    }

    return FR_SUCC;
}

/*!
 *\brief TC_REFERENCE 解析
 *
 *\arg p_st_data 输入的数据
 *     p_st_body_data 上报数据输出列表
 *     i_use_request  请求 或者 响应(FR_YES:FR_NO)
 *     p_i_deep       递增序列号
 *     pp_rmi_head    上报信息列表
 *     pp_rmi_root    申请的结构体列表 (管理内存用)
 *     p_u32_passHandle handle
 *     p_parent        上一层结构体名
 *     p_prefix         前缀名 (例如 http.rmi  或者 rmi)
 *
 * \return              FR_SUCC
 *                      FR_FAIL
 *
 */
int readHandle(Frbyte_Packet *p_st_data, Frreport_body_data *p_st_body_data, int i_use_request
               , int *p_i_deep, rmiDataParent **pp_rmi_head, rmiDataParent **pp_rmi_root
               , uint32_t *p_u32_passHandle, char *p_parent, char *p_prefix)
{
    uint8_t u8_tc = 0;
    int i_ret = 0;
    uint32_t passHandle = 0;
    rmiDataParent *p_rmi_head = NULL;
    rmiDataParent *p_rmi_head_tmp = NULL;
    char arr_key[128];

    //todo handle 处理
    if(p_st_data == NULL || p_st_body_data == NULL || p_i_deep == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_st_data, &u8_tc);
    if(i_ret == FR_FAIL || u8_tc != TC_REFERENCE)
        return FR_FAIL;

    //passHandle = bin.readInt() - baseWireHandle;

    i_ret = bytebuff_get_int(p_st_data, 4, &passHandle, BYTE_BIG_ENDIAN);
    if(i_ret == FR_FAIL || passHandle > *p_u32_passHandle)
        return FR_FAIL;

    //
    if(pp_rmi_head)
    {
        //作为value上报
        if(*pp_rmi_head)
        {
            p_rmi_head = *pp_rmi_head;
            if(p_rmi_head->p_object_type == NULL && p_rmi_head->i_type_handle == 0)
            {
                p_rmi_head->i_type_handle = passHandle;
                return FR_SUCC;
            }
            
            if(p_rmi_head->p_object_type)
            {
                if(p_rmi_head->p_name)
                {
                    if(i_use_request)
                        snprintf(arr_key, sizeof(arr_key), "request.%s.%d.%s.handle", p_prefix, *p_i_deep, p_rmi_head->p_name);
                    else
                        snprintf(arr_key, sizeof(arr_key), "response.%s.%d.%s.handle", p_prefix, *p_i_deep, p_rmi_head->p_name);
                }
                else
                {
                    if(i_use_request)
                        snprintf(arr_key, sizeof(arr_key), "request.%s.%d.handle", p_prefix, *p_i_deep);
                    else
                        snprintf(arr_key, sizeof(arr_key), "response.%s.%d.handle", p_prefix, *p_i_deep);
                }
    
                (*p_i_deep)++;
                return frreport_body_l7_add_int(p_st_body_data, arr_key, passHandle);
            }

        }
        else
        {
            //作为一个类型声明
            p_rmi_head_tmp = rmiHeadNew();
            p_rmi_head_tmp->i_type_handle = passHandle;

//            *pp_rmi_head = p_rmi_head;
            rmiDataAddChild(pp_rmi_head, &p_rmi_head_tmp);
            rmiDataAddBrother(pp_rmi_root, &p_rmi_head_tmp);
            return FR_SUCC;
        }
    }

    return FR_SUCC;
}


/*!
 *\brief TC_CLASS 解析
 *
 *\arg p_st_data 输入的数据
 *     p_st_body_data 上报数据输出列表
 *     i_use_request  请求 或者 响应(FR_YES:FR_NO)
 *     p_i_deep       递增序列号
 *     pp_rmi_head    上报信息列表
 *     pp_rmi_root    申请的结构体列表 (管理内存用)
 *     p_u32_passHandle handle
 *     p_parent        上一层结构体名
 *     p_prefix         前缀名 (例如 http.rmi  或者 rmi)
 *
 * \return              FR_SUCC
 *                      FR_FAIL
 *
 */
int readClass(Frbyte_Packet *p_st_data, Frreport_body_data *p_st_body_data, int i_use_request
              , int *p_i_deep, rmiDataParent **pp_rmi_head, rmiDataParent **pp_rmi_root
              , uint32_t *p_u32_passHandle, char *p_parent, char *p_prefix)
{
    uint8_t u8_tc = 0;
    int i_ret = 0;
    rmiDataParent *p_rmi_head = NULL;

    if(p_st_data == NULL || p_st_body_data == NULL || p_i_deep == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_st_data, &u8_tc);
    if(i_ret == FR_FAIL || u8_tc != TC_CLASS)
        return FR_FAIL;

    //ObjectStreamClass desc = readClassDesc(false);
    i_ret = readClassDesc(p_st_data, p_st_body_data, i_use_request, p_i_deep, &p_rmi_head, pp_rmi_root
                          , p_u32_passHandle, p_parent, p_prefix);
    if(i_ret == FR_FAIL)
        return FR_FAIL;
    
    
    (*p_u32_passHandle)++;

    rmiDataAddChild(pp_rmi_head, &p_rmi_head);
    
    return FR_SUCC;

}

/*!
 *\brief class 声明 解析
 *
 *\arg p_st_data 输入的数据
 *     p_st_body_data 上报数据输出列表
 *     i_use_request  请求 或者 响应(FR_YES:FR_NO)
 *     p_i_deep       递增序列号
 *     pp_rmi_head    上报信息列表
 *     pp_rmi_root    申请的结构体列表 (管理内存用)
 *     p_u32_passHandle handle
 *     p_parent        上一层结构体名
 *     p_prefix         前缀名 (例如 http.rmi  或者 rmi)
 *
 * \return              FR_SUCC
 *                      FR_FAIL
 *
 */
int readClassDesc(Frbyte_Packet *p_st_data, Frreport_body_data *p_st_body_data, int i_use_request
                  , int *p_i_deep, rmiDataParent **pp_rmi_head, rmiDataParent **pp_rmi_root
                  , uint32_t *p_u32_passHandle, char *p_parent, char *p_prefix)
{
    uint8_t u8_tc = 0;
    int i_ret = 0;
    rmiDataParent *p_rmi_head = NULL;

    if(p_st_data == NULL || p_st_body_data == NULL || p_i_deep == NULL || pp_rmi_head == NULL)
        return FR_FAIL;

    i_ret = bytebuff_peek_char(p_st_data, &u8_tc);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    switch (u8_tc)
    {
        case TC_NULL:
            i_ret = readNull(p_st_data, p_st_body_data,i_use_request, p_i_deep, &p_rmi_head, pp_rmi_root
                             , p_u32_passHandle, p_parent, p_prefix);
            break;

        case TC_REFERENCE:
            i_ret = readHandle(p_st_data, p_st_body_data,i_use_request, p_i_deep, &p_rmi_head, pp_rmi_root
                               , p_u32_passHandle, p_parent, p_prefix);
            break;

        case TC_PROXYCLASSDESC:
            i_ret = readProxyDesc(p_st_data, p_st_body_data,i_use_request, p_i_deep, &p_rmi_head, pp_rmi_root
                                  , p_u32_passHandle, p_parent, p_prefix);
            break;

        case TC_CLASSDESC:
            i_ret = readNonProxyDesc(p_st_data, p_st_body_data,i_use_request, p_i_deep, &p_rmi_head, pp_rmi_root
                                     , p_u32_passHandle, p_parent, p_prefix);
            break;

        default:
            return FR_FAIL;
    }

    if(i_ret == FR_FAIL)
        return FR_FAIL;
    
    //todo
    if(p_rmi_head && p_rmi_head->hasData)
    {

        rmi_report(p_st_data, p_st_body_data, i_use_request, p_i_deep, p_rmi_head, pp_rmi_root, p_u32_passHandle, p_parent, p_prefix);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
        
        return FR_SUCC;
    }
    
    rmiDataAddChild(pp_rmi_head, &p_rmi_head);
    return FR_SUCC;

}

/*!
 *\brief 跳过blockdata
 *
 *\arg p_st_data 输入的数据
 * \return              FR_SUCC
 *                      FR_FAIL
 *
 */
int readBlockHeader(Frbyte_Packet *p_st_data)
{
    int i_ret = 0;
    uint32_t u32_len = 0;
    uint8_t u8_tc = 0;

    if(p_st_data == NULL)
        return FR_FAIL;

    i_ret = bytebuff_peek_char(p_st_data, &u8_tc);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    if(u8_tc == TC_BLOCKDATA)
    {
        bytebuff_skip(p_st_data, 1);

        i_ret = bytebuff_get_int(p_st_data, 1, &u32_len, BYTE_BIG_ENDIAN);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
    }
    else if(u8_tc == TC_BLOCKDATALONG)
    {
        bytebuff_skip(p_st_data, 1);

        i_ret = bytebuff_get_int(p_st_data, 4, &u32_len, BYTE_BIG_ENDIAN);
        if(i_ret == FR_FAIL)
            return FR_FAIL;

    }
    else
        return FR_FAIL;


    return bytebuff_skip(p_st_data, u32_len);
}

/*!
 *\brief 跳过blockdata
 *
 *\arg p_st_data 输入的数据
 * \return              FR_SUCC
 *                      FR_FAIL
 *
 */
int readBlockHeader(Frbyte_Packet *p_st_data, Frreport_body_data *p_st_body_data, int i_use_request
                    , int *p_i_deep, rmiDataParent **pp_rmi_head, rmiDataParent **pp_rmi_root
                    , uint32_t *p_u32_passHandle, char *p_parent, char *p_prefix)
{
    int i_ret = 0;
    uint32_t u32_len = 0;
    uint8_t u8_tc = 0;
    char *p_string = NULL;
    char arr_key[256];

    if(p_st_data == NULL)
        return FR_FAIL;

    i_ret = bytebuff_peek_char(p_st_data, &u8_tc);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    if(u8_tc == TC_BLOCKDATA)
    {
        bytebuff_skip(p_st_data, 1);

        i_ret = bytebuff_get_int(p_st_data, 1, &u32_len, BYTE_BIG_ENDIAN);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
    }
    else if(u8_tc == TC_BLOCKDATALONG)
    {
        bytebuff_skip(p_st_data, 1);

        i_ret = bytebuff_get_int(p_st_data, 4, &u32_len, BYTE_BIG_ENDIAN);
        if(i_ret == FR_FAIL)
            return FR_FAIL;

    }
    else
        return FR_FAIL;

    p_string = (char *)frmalloc(u32_len + 1);
    if(p_string == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_bytes(p_st_data, p_string, u32_len);
    if(i_ret == FR_FAIL)
    {
        frfree(p_string);
        return FR_FAIL;
    }

    p_string[u32_len] = '\0';

    if(i_use_request)
        snprintf(arr_key, sizeof(arr_key), "request.%s.block.%d", p_prefix, *p_i_deep);
    else
        snprintf(arr_key, sizeof(arr_key), "response.%s.block.%d", p_prefix, *p_i_deep);

    (*p_i_deep)++;
    i_ret = frreport_body_l7_add_bin(p_st_body_data, arr_key, p_string, u32_len);
    if(i_ret == FR_FAIL)
    {
        frfree(p_string);
        return FR_FAIL;
    }

    (*p_u32_passHandle)++;
    frfree(p_string);
    return FR_SUCC;

    //return bytebuff_skip(p_st_data, u32_len);
}


/*!
 *\brief TC_PROXYCLASSDESC 解析
 *
 *\arg p_st_data 输入的数据
 *     p_st_body_data 上报数据输出列表
 *     i_use_request  请求 或者 响应(FR_YES:FR_NO)
 *     p_i_deep       递增序列号
 *     pp_rmi_head    上报信息列表
 *     pp_rmi_root    申请的结构体列表 (管理内存用)
 *     p_u32_passHandle handle
 *     p_parent        上一层结构体名
 *     p_prefix         前缀名 (例如 http.rmi  或者 rmi)
 *
 * \return              FR_SUCC
 *                      FR_FAIL
 *
 */
int readProxyDesc(Frbyte_Packet *p_st_data, Frreport_body_data *p_st_body_data, int i_use_request
                  , int *p_i_deep, rmiDataParent **pp_rmi_head, rmiDataParent **pp_rmi_root
                  , uint32_t *p_u32_passHandle, char *p_parent, char *p_prefix)
{
    uint8_t u8_tc = 0;
    int i_ret = 0;
    int numIfaces = 0;
    rmiDataParent *p_rmi_head = NULL, *p_rmi_head_tmp = NULL;

    if(p_st_data == NULL || p_st_body_data == NULL || p_i_deep == NULL || pp_rmi_head == NULL)
        return FR_FAIL;
    
    i_ret = bytebuff_get_char(p_st_data, &u8_tc);
    if(i_ret == FR_FAIL || u8_tc != TC_PROXYCLASSDESC)
        return FR_FAIL;

    i_ret = bytebuff_get_int(p_st_data, 4, (uint32_t *)&numIfaces, BYTE_BIG_ENDIAN);
    if(i_ret == FR_FAIL)
        return FR_FAIL;
    
    while (numIfaces)
    {
        if(p_rmi_head)
        {
            p_rmi_head_tmp = rmiHeadNew();
            if(p_rmi_head_tmp == NULL)
                return FR_FAIL;
    
            rmiDataAddBrother(pp_rmi_root, &p_rmi_head_tmp);
            p_rmi_head_tmp->p_name = readUTF(p_st_data);
            if(p_rmi_head_tmp->p_name == NULL)
                return FR_FAIL;
            

            rmiDataAddChild(&p_rmi_head, &p_rmi_head_tmp);
            p_rmi_head_tmp = NULL;

        }
        else
        {
            p_rmi_head = rmiHeadNew();
            if(p_rmi_head == NULL)
                return FR_FAIL;
    
            rmiDataAddBrother(pp_rmi_root, &p_rmi_head);
            p_rmi_head->passhandle = *p_u32_passHandle;
            (*p_u32_passHandle)++;
            
            p_rmi_head->p_name = readUTF(p_st_data);
            if(p_rmi_head->p_name == NULL)
                return FR_FAIL;
        }

        numIfaces--;
    }

//    bout.setBlockDataMode(true);
//    annotateProxyClass(cl);
//    bout.setBlockDataMode(false);

//    i_ret = readBlockHeader(p_st_data);
//    if(i_ret == FR_FAIL)
//        return FR_FAIL;
//
////    bout.writeByte(TC_ENDBLOCKDATA);
//    i_ret = bytebuff_get_char(p_st_data, &u8_tc);
//    if(i_ret == FR_FAIL || i_ret != TC_ENDBLOCKDATA)
//        return FR_FAIL;

    //跳过78
    p_rmi_head_tmp = NULL;
    i_ret = skipCustomData(p_st_data, p_st_body_data, i_use_request, p_i_deep, &p_rmi_head_tmp, pp_rmi_root
                           , p_u32_passHandle, p_parent, p_prefix);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    //超类声明
    i_ret = readClassDesc(p_st_data, p_st_body_data, i_use_request, p_i_deep, &p_rmi_head_tmp, pp_rmi_root
                          , p_u32_passHandle, p_parent, p_prefix);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    p_rmi_head->super = p_rmi_head_tmp;
    
    rmiDataAddChild(pp_rmi_head, &p_rmi_head);
    return FR_SUCC;

}

int readClassDescriptor(Frbyte_Packet *p_st_data, Frreport_body_data *p_st_body_data, int i_use_request
                        , int *p_i_deep, rmiDataParent **pp_rmi_head, rmiDataParent **pp_rmi_root
                        , uint32_t *p_u32_passHandle, char *p_parent, char *p_prefix)
{
    rmiDataParent *p_rmi_head = NULL;
    int i_ret = 0;

    if(p_st_data == NULL || p_st_body_data == NULL || p_i_deep == NULL || p_u32_passHandle == NULL)
        return FR_FAIL;

    //    desc.writeNonProxy(this);
    i_ret = object_writeNonProxy(p_st_data, p_st_body_data, i_use_request, p_i_deep, &p_rmi_head
                                 , pp_rmi_root, p_u32_passHandle, p_parent, p_prefix);
    if(i_ret == FR_FAIL)
        return FR_FAIL;
    
//    *pp_rmi_head = p_rmi_head;
    rmiDataAddChild(pp_rmi_head, &p_rmi_head);
    return FR_SUCC;

}

/*!
 *\brief TC_CLASSDESC 解析
 *
 *\arg p_st_data 输入的数据
 *     p_st_body_data 上报数据输出列表
 *     i_use_request  请求 或者 响应(FR_YES:FR_NO)
 *     p_i_deep       递增序列号
 *     pp_rmi_head    上报信息列表
 *     pp_rmi_root    申请的结构体列表 (管理内存用)
 *     p_u32_passHandle handle
 *     p_parent        上一层结构体名
 *     p_prefix         前缀名 (例如 http.rmi  或者 rmi)
 *
 * \return              FR_SUCC
 *                      FR_FAIL
 *
 */
int readNonProxyDesc(Frbyte_Packet *p_st_data, Frreport_body_data *p_st_body_data, int i_use_request
                     , int *p_i_deep, rmiDataParent **pp_rmi_head, rmiDataParent **pp_rmi_root
                     , uint32_t *p_u32_passHandle, char *p_parent, char *p_prefix)
{
    uint8_t u8_tc = 0;
    int i_ret = 0;
    rmiDataParent *p_rmi_head = NULL;
    rmiDataParent *p_rmi_head_tmp = NULL;

    if(p_st_data == NULL || p_st_body_data == NULL || p_i_deep == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_st_data, &u8_tc);
    if(i_ret == FR_FAIL || u8_tc != TC_CLASSDESC)
        return FR_FAIL;

    //writeClassDescriptor(desc);
    i_ret = readClassDescriptor(p_st_data, p_st_body_data, i_use_request, p_i_deep, &p_rmi_head, pp_rmi_root
                                , p_u32_passHandle, p_parent, p_prefix);
    if(i_ret == FR_FAIL)
        return FR_FAIL;
    
    i_ret = skipCustomData(p_st_data, p_st_body_data, i_use_request, p_i_deep, &p_rmi_head_tmp
                           , pp_rmi_root, p_u32_passHandle, p_parent, p_prefix);
    if(i_ret == FR_FAIL)
        return FR_FAIL;
    
    //超类声明
    i_ret = readClassDesc(p_st_data, p_st_body_data, i_use_request, p_i_deep, &p_rmi_head_tmp
                          , pp_rmi_root, p_u32_passHandle, p_parent, p_prefix);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    //todo
    p_rmi_head->super = p_rmi_head_tmp;
    
    //跳过blockdata
    if(p_rmi_head->hasBlockExternalData)
    {
        i_ret = readBlockHeader(p_st_data, p_st_body_data, i_use_request, p_i_deep, pp_rmi_head, pp_rmi_root
                , p_u32_passHandle, p_parent, p_prefix);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
        
    }
    
    rmiDataAddChild(pp_rmi_head, &p_rmi_head);
    
    return FR_SUCC;

}


/*!
 *\brief TC_STRING 解析
 *
 *\arg p_st_data 输入的数据
 *     p_st_body_data 上报数据输出列表
 *     i_use_request  请求 或者 响应(FR_YES:FR_NO)
 *     p_i_deep       递增序列号
 *     pp_rmi_head    上报信息列表
 *     pp_rmi_root    申请的结构体列表 (管理内存用)
 *     p_u32_passHandle handle
 *     p_parent        上一层结构体名
 *     p_prefix         前缀名 (例如 http.rmi  或者 rmi)
 *
 * \return              FR_SUCC
 *                      FR_FAIL
 *
 */
int readString(Frbyte_Packet *p_st_data, Frreport_body_data *p_st_body_data, int i_use_request
               , int *p_i_deep, rmiDataParent **pp_rmi_head, rmiDataParent **pp_rmi_root
               , uint32_t *p_u32_passHandle, char *p_parent, char *p_prefix)
{
    uint8_t u8_tc = 0;
    int i_ret = 0;
    char *p_string = NULL;
    uint64_t u64_len = 0;
    char arr_key[128];
    rmiDataParent *p_rmi_head = NULL;

    if(p_st_data == NULL || p_st_body_data == NULL || p_i_deep == NULL)
        return FR_FAIL;


    i_ret = bytebuff_get_char(p_st_data, &u8_tc);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    if(u8_tc == TC_STRING)
    {
        i_ret = bytebuff_get_long(p_st_data, 2, &u64_len, BYTE_BIG_ENDIAN);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
    }
    else if(u8_tc == TC_LONGSTRING)
    {
        i_ret = bytebuff_get_long(p_st_data, 8, &u64_len, BYTE_BIG_ENDIAN);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
    }
    else
        return FR_FAIL;

    p_string = (char *)frmalloc(u64_len + 1);
    if(p_string == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_bytes(p_st_data, p_string, u64_len);
    if(i_ret == FR_FAIL)
    {
        frfree(p_string);
        return FR_FAIL;
    }

    p_string[u64_len] = '\0';


    p_rmi_head = *pp_rmi_head;
    if(p_rmi_head)
    {
        if(p_rmi_head->p_object_type == NULL && p_rmi_head->i_type_handle == 0)
        {
            p_rmi_head->p_object_type = p_string;
            p_rmi_head->passhandle = *p_u32_passHandle;
            (*p_u32_passHandle)++;
            return FR_SUCC;
        }
    
        if(p_parent)
        {
            if(p_rmi_head->p_name)
            {
                if(i_use_request)
                    snprintf(arr_key, sizeof(arr_key), "request.%s.%d.%s.%s", p_prefix, *p_i_deep, p_parent, p_rmi_head->p_name);
                else
                    snprintf(arr_key, sizeof(arr_key), "response.%s.%d.%s.%s", p_prefix, *p_i_deep, p_parent, p_rmi_head->p_name);
            }
            else
            {
                if(i_use_request)
                    snprintf(arr_key, sizeof(arr_key), "request.%s.%d.%s", p_prefix, *p_i_deep, p_parent);
                else
                    snprintf(arr_key, sizeof(arr_key), "response.%s.%d.%s", p_prefix, *p_i_deep, p_parent);
            }
        }
        else
        {
            if(p_rmi_head->p_name)
            {
                if(i_use_request)
                    snprintf(arr_key, sizeof(arr_key), "request.%s.%d.%s", p_prefix, *p_i_deep, p_rmi_head->p_name);
                else
                    snprintf(arr_key, sizeof(arr_key), "response.%s.%d.%s", p_prefix, *p_i_deep, p_rmi_head->p_name);
            }
            else
            {
                if(i_use_request)
                    snprintf(arr_key, sizeof(arr_key), "request.%s.%d", p_prefix, *p_i_deep);
                else
                    snprintf(arr_key, sizeof(arr_key), "response.%s.%d", p_prefix, *p_i_deep);
            }
        }
        
    
        (*p_i_deep)++;
        i_ret = frreport_body_l7_add_str(p_st_body_data, arr_key, p_string);
        if(i_ret == FR_FAIL)
        {
            frfree(p_string);
            return FR_FAIL;
        }
    
        (*p_u32_passHandle)++;
        frfree(p_string);
        return FR_SUCC;
    }
    else
    {
        p_rmi_head = rmiHeadNew();
        p_rmi_head->p_name = p_string;
        
        rmiDataAddChild(pp_rmi_head, &p_rmi_head);
        rmiDataAddBrother(pp_rmi_root, &p_rmi_head);
        return FR_SUCC;
    }

}


/*!
 *\brief TC_ARRAY 解析
 *
 *\arg p_st_data 输入的数据
 *     p_st_body_data 上报数据输出列表
 *     i_use_request  请求 或者 响应(FR_YES:FR_NO)
 *     p_i_deep       递增序列号
 *     pp_rmi_head    上报信息列表
 *     pp_rmi_root    申请的结构体列表 (管理内存用)
 *     p_u32_passHandle handle
 *     p_parent        上一层结构体名
 *     p_prefix         前缀名 (例如 http.rmi  或者 rmi)
 *
 * \return              FR_SUCC
 *                      FR_FAIL
 *
 */
int readArray(Frbyte_Packet *p_st_data, Frreport_body_data *p_st_body_data, int i_use_request
              , int *p_i_deep, rmiDataParent **pp_rmi_head, rmiDataParent **pp_rmi_root
              , uint32_t *p_u32_passHandle, char *p_parent, char *p_prefix)
{
    uint8_t u8_tc = 0;
    int i_ret = 0;
    uint32_t u32_arr_size = 0;
    unsigned int ui_size = 0;
    rmiDataParent *p_rmi_head = NULL;
    rmiDataParent *p_rmi_head_tmp = NULL;
    uint8_t u8_type = 0;

    if(p_st_data == NULL || p_st_body_data == NULL || p_i_deep == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_st_data, &u8_tc);
    if(i_ret == FR_FAIL || u8_tc != TC_ARRAY)
        return FR_FAIL;

    i_ret = readClassDesc(p_st_data, p_st_body_data, i_use_request, p_i_deep, &p_rmi_head
                          , pp_rmi_root, p_u32_passHandle, p_parent, p_prefix);
    if(i_ret == FR_FAIL || p_rmi_head == NULL)
        return FR_FAIL;
    
    (*p_u32_passHandle)++;
    
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_arr_size, BYTE_BIG_ENDIAN);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    //todo 根据 命名来判别是否为object
    if(p_rmi_head->p_name)
    {
        u8_type = (uint8_t)p_rmi_head->p_name[1];
    }
    else
    {
        p_rmi_head_tmp = rmiTypeFind(*pp_rmi_root, p_rmi_head->i_type_handle);
        if(p_rmi_head_tmp == NULL)
            return FR_FAIL;
        
        u8_type = (uint8_t)p_rmi_head_tmp->p_name[1];
        p_rmi_head_tmp = NULL;
    }

    if(u8_type == 'L')
    {
        while (u32_arr_size)
        {
            i_ret = readObject0(p_st_data, p_st_body_data, i_use_request, p_i_deep, &p_rmi_head_tmp
                                , pp_rmi_root, p_u32_passHandle, p_parent, p_prefix);
            if(i_ret == FR_FAIL)
                break;
        
            rmiDataAddChild(&p_rmi_head, &p_rmi_head_tmp);
            p_rmi_head_tmp = NULL;
        
            u32_arr_size--;
            if(u32_arr_size == 0)
            {
                rmiDataAddChild(pp_rmi_head, &p_rmi_head);
                return FR_SUCC;
            }
        }
    }
    else
    {
        //todo
        switch (u8_type)
        {
            case 'Z':
            case 'B':
                ui_size = 1;
                break;
        
                //Short
            case 'C':
            case 'S':
                ui_size = 2;
                break;
        
                //Int
            case 'I':
                ui_size = 4;
                break;
        
                //Long
            case 'J':
            case 'F':
            case 'D':
                ui_size = 8;
                break;
                //不是private
            default:
                break;
        }

        ui_size = ui_size * u32_arr_size;

        i_ret = bytebuff_skip(p_st_data, ui_size);
        if (i_ret == FR_FAIL)
            return FR_FAIL;
    }
    
    rmiDataAddChild(pp_rmi_head, &p_rmi_head);
    return FR_SUCC;

}

/*!
 *\brief TC_ENUM 解析
 *
 *\arg p_st_data 输入的数据
 *     p_st_body_data 上报数据输出列表
 *     i_use_request  请求 或者 响应(FR_YES:FR_NO)
 *     p_i_deep       递增序列号
 *     pp_rmi_head    上报信息列表
 *     pp_rmi_root    申请的结构体列表 (管理内存用)
 *     p_u32_passHandle handle
 *     p_parent        上一层结构体名
 *     p_prefix         前缀名 (例如 http.rmi  或者 rmi)
 *
 * \return              FR_SUCC
 *                      FR_FAIL
 *
 */
int readEnum(Frbyte_Packet *p_st_data, Frreport_body_data *p_st_body_data, int i_use_request
             , int *p_i_deep, rmiDataParent **pp_rmi_head, rmiDataParent **pp_rmi_root
             , uint32_t *p_u32_passHandle, char *p_parent, char *p_prefix)
{
    uint8_t u8_tc = 0;
    int i_ret = 0;
    rmiDataParent *p_rmi_head = NULL;
    uint32_t u32_tmp = 0;

    if(p_st_data == NULL || p_st_body_data == NULL || p_i_deep == NULL || pp_rmi_head == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_st_data, &u8_tc);
    if(i_ret == FR_FAIL || u8_tc != TC_ENUM)
        return FR_FAIL;

    i_ret = readClassDesc(p_st_data, p_st_body_data, i_use_request, p_i_deep, &p_rmi_head, pp_rmi_root
                          , p_u32_passHandle, p_parent, p_prefix);
    if(i_ret == FR_FAIL || p_rmi_head == NULL)
        return FR_FAIL;
    
    (*p_u32_passHandle)++;
    
//    writeString(en.name(), false);
//    enumConstantName:
//    (String)object
    i_ret = readString(p_st_data, p_st_body_data, i_use_request, p_i_deep, &p_rmi_head, NULL, &u32_tmp, p_parent, p_prefix);
    if(i_ret == FR_FAIL)
        return FR_FAIL;
    
    rmiDataAddChild(pp_rmi_head, &p_rmi_head);
    return FR_SUCC;
}


/*!
 *\brief TC_OBJECT 解析
 *
 *\arg p_st_data 输入的数据
 *     p_st_body_data 上报数据输出列表
 *     i_use_request  请求 或者 响应(FR_YES:FR_NO)
 *     p_i_deep       递增序列号
 *     pp_rmi_head    上报信息列表
 *     pp_rmi_root    申请的结构体列表 (管理内存用)
 *     p_u32_passHandle handle
 *     p_parent        上一层结构体名
 *     p_prefix         前缀名 (例如 http.rmi  或者 rmi)
 *
 * \return              FR_SUCC
 *                      FR_FAIL
 *
 */
int readOrdinaryObject(Frbyte_Packet *p_st_data, Frreport_body_data *p_st_body_data, int i_use_request
                       , int *p_i_deep, rmiDataParent **pp_rmi_head, rmiDataParent **pp_rmi_root
                       , uint32_t *p_u32_passHandle, char *p_parent, char *p_prefix)
{
    uint8_t u8_tc = 0;
    int i_ret = 0;
    rmiDataParent *p_rmi_head = NULL;
    rmiDataParent *p_rmi_head_tmp = NULL;

    if(p_st_data == NULL || p_st_body_data == NULL || p_i_deep == NULL)
        return FR_FAIL;

//    bout.writeByte(TC_OBJECT);
    i_ret = bytebuff_get_char(p_st_data, &u8_tc);
    if(i_ret == FR_FAIL || u8_tc != TC_OBJECT)
        return FR_FAIL;

//    writeClassDesc(desc, false);
    i_ret = readClassDesc(p_st_data, p_st_body_data, i_use_request, p_i_deep, &p_rmi_head, pp_rmi_root
                          , p_u32_passHandle, p_parent, p_prefix);
    if(i_ret == FR_FAIL)
        return FR_FAIL;
    
    (*p_u32_passHandle)++;

    i_ret = rmi_report(p_st_data, p_st_body_data, i_use_request, p_i_deep, p_rmi_head, pp_rmi_root
                       , p_u32_passHandle, p_parent, p_prefix);
    
    if(i_ret == FR_FAIL)
        return FR_FAIL;
    
    if(p_rmi_head && p_rmi_head->externalizable)
    {
        //        writeExternalData((Externalizable) obj);
        i_ret = skipCustomData(p_st_data, p_st_body_data, i_use_request, p_i_deep, &p_rmi_head_tmp, pp_rmi_root
                               , p_u32_passHandle, p_rmi_head->p_name, p_prefix);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
    }
    
//    rmiDataAddChild(pp_rmi_head, &p_rmi_head);
    return FR_SUCC;
}


/*!
 *\brief TC_OBJECT 解析
 *
 *\arg p_st_data 输入的数据
 *     p_st_body_data 上报数据输出列表
 *     i_use_request  请求 或者 响应(FR_YES:FR_NO)
 *     p_prefix         前缀名 (例如 http.rmi  或者 rmi)
 *
 * \return              FR_SUCC
 *                      FR_FAIL
 *
 */
int readRmi(Frbyte_Packet *p_st_data, Frreport_body_data *p_st_body_data, int i_use_request, char *p_prefix)
{
    int i_ret = 0;
    uint32_t u32_len = 0;
    char arr_tmp[5];
    int i_deep = 0;
    
    if(p_st_data == NULL || p_st_body_data == NULL || p_prefix == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_int(p_st_data, 4, &u32_len, BYTE_BIG_ENDIAN);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    if(u32_len != (unsigned int) bytebuff_remaining(p_st_data))
        return FR_FAIL;

    i_ret = bytebuff_get_bytes(p_st_data, arr_tmp, 4);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    if(memcmp(arr_tmp, "\x72\x71\x89", 3) != 0)
        return FR_FAIL;


    i_ret = readStreamHeader(p_st_data);
    if(i_ret == FR_FAIL)
        return FR_FAIL;
    
    i_ret = readObject(p_st_data, p_st_body_data, i_use_request, &i_deep, p_prefix);
    if(i_ret == FR_FAIL)
        return FR_FAIL;
    
    return i_ret;

}

/*!http rmi 格式判断
 *
 * \arg p_tcp_body          (数据包内容)
 * \arg ui_tcp_body_len     (数据包长度)
 * \arg i_flag_chunked      (是不是chunked格式)
 *
 * \return                  0:符合rmi
 *                          1：不符合
 *                          2：不能确定
 * */
int http_rmi_detect(char *p_tcp_body, unsigned int ui_tcp_body_len, int i_flag_chunked)
{
    
    if(p_tcp_body == NULL || ui_tcp_body_len < 8)
        return 2;
    
    if(i_flag_chunked == 0)
    {
        if(memcmp(p_tcp_body + 4, "\x72\x71\x89", 3) == 0)
            return 0;
        else
            return 1;
    }
    else
    {
        
    }
        return 0;
    
    
}